package org.elip.stewiemaze.server;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.google.appengine.repackaged.com.google.common.util.Base64;
import com.google.appengine.repackaged.com.google.common.util.Base64DecoderException;
import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;

public class SignedRequestDecoder {

	public static byte[] base64_url_decode(String input) throws IOException {
		try {
			return Base64.decode(input);
		} catch (Base64DecoderException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return null;
	}

	@SuppressWarnings("rawtypes")
	public static Map parse_signed_request(String input, String secret) throws Exception {
		return parse_signed_request(input, secret, 3600);
	}

	@SuppressWarnings({ "unused", "rawtypes" })
	public static Map parse_signed_request(String input, String secret, int max_age) throws Exception {
		String[] split = input.split("[.]", 2);

		String encoded_sig = split[0];
		String encoded_envelope = split[1];


		String DecMsg = new String(base64_url_decode(encoded_envelope));

		Map envelope = getMapOfJsonString(DecMsg);


		String algorithm = (String) envelope.get("algorithm");

		if (!algorithm.equals("AES-256-CBC HMAC-SHA256") && !algorithm.equals("HMAC-SHA256")) {
			throw new Exception("Invalid request. (Unsupported algorithm.)");
		}

		byte[] key = secret.getBytes();
		SecretKey hmacKey = new SecretKeySpec(key, "HMACSHA256");
		Mac mac = Mac.getInstance("HMACSHA256");
		mac.init(hmacKey);
		byte[] digest = mac.doFinal(encoded_envelope.getBytes());

		return envelope;

	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static Map getMapOfJsonString(String DecMsg) throws JSONException {
		JSONObject jsonObject = null;

		try {
			jsonObject = new JSONObject(DecMsg);
		} catch (JSONException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		Map envelope = new HashMap<String, String>();

		String[] names = JSONObject.getNames(jsonObject);
		for (String name : names) {
			envelope.put(name, jsonObject.get(name));

		}
		return envelope;
	}

}
